<template>
	<el-drawer
	  v-model="dialog.visible"
	  :title="dialog.title"
	  append-to-body
	  @close="closeDialog"
	  :close-on-click-modal="false"
	  size="850"
	>
		<el-scrollbar>
		<el-form
			ref="formRef"
			:model="formData"
			:rules="formRules"
			label-width="180px"
		>
		
			<el-form-item label="输入字段" prop="inputFieldIdentifier">
				<el-select v-model="formData.inputFieldIdentifier"   placeholder="请选择输入字段名" >
					<el-option
					  v-for="item in standardFields"
					  :key="item.outputFieldIdentifier"
					  :label="item.outputFieldName"
					  :value="item.outputFieldIdentifier"
					  @click="handleInputFieldSelect(item)"
					/>
				</el-select>
			</el-form-item>
			
			<!-- 输出配置 -->
			<div class="section-title">
				<span class="title-form_primary">输出配置</span>
			</div>
			
			<el-form-item label="输出日期格式定义" prop="outputFieldDateFormatSrc" v-if="['dateString'].includes(formData.outputFieldType)">
				<el-radio-group v-model="formData.outputFieldDateFormatSrc" class="flex-container">
					<el-radio value="input">自定义</el-radio>
					<el-radio value="select">下拉选择日期格式</el-radio>
				</el-radio-group>
			</el-form-item>
			
			<el-form-item label="输出字段格式" prop="outputFieldFormat" v-if="['dateString'].includes(formData.outputFieldType)">
				<template v-if="formData.outputFieldDateFormatSrc === 'select'">
					<el-select v-model="formData.outputFieldFormat" placeholder="请选择输出日期格式">
						<el-option label="yyyy-MM-dd" value="yyyy-MM-dd" />
						<el-option label="yyyy-MM-dd HH:mm:ss" value="yyyy-MM-dd HH:mm:ss" />
						<el-option label="yyyy年MM月dd日" value="yyyy年MM月dd日" />
						<el-option label="yyyy年MM月dd日 HH时mm分ss秒" value="yyyy年MM月dd日 HH时mm分ss秒" />
						<el-option label="HH:mm:ss" value="HH:mm:ss" />
						<el-option label="HH时mm分ss秒" value="HH时mm分ss秒" />
						<el-option label="yyyy/MM/dd" value="yyyy/MM/dd" />
						<el-option label="yyyy/MM/dd HH:mm:ss" value="yyyy/MM/dd HH:mm:ss" />
						<el-option label="yyyyMMdd" value="yyyyMMdd" />
						<el-option label="yyyyMMddHHmmss" value="yyyyMMddHHmmss" />
					</el-select>
				</template>
				<template v-else>
					<el-input v-model="formData.outputFieldFormat" placeholder="请输入自定义日期格式" />
				</template>
			</el-form-item>
			
			<el-form-item label="输出字段保留小数位" prop="outputFieldDecimalPoint" v-if="['float','double'].includes(formData.outputFieldType)">
				<el-input-number v-model="formData.outputFieldDecimalPoint" placeholder="请输入字段保留小数位" :min="0" :max="32" />
			</el-form-item>
			
			<el-form-item label="输出字段值来源" prop="outputValueFromInput">
				<el-select v-model="formData.outputValueFromInput">
					<el-option label="输入值" value="input" />
					<el-option label="常量值" value="constant" />
					<el-option label="系统时间" value="curSystemDate" />
					<el-option label="OLTP" value="OLTP" />
					<el-option label="缓存(Redis)" value="redis" />
				</el-select>
			</el-form-item>
			
			<!-- OLTP数据库相关配置 -->
			<template v-if="formData.outputValueFromInput === 'OLTP'">
				<el-form-item label="数据源" prop="outputValueDatasourceId">
					<el-select v-model="formData.outputValueDatasourceId" placeholder="请选择数据源">
						<el-option
						  v-for="item in datasourceOptions"
						  :key="item.id"
						  :label="item.name"
						  :value="item.id"
						/>
					</el-select>
				</el-form-item>
				
				<el-form-item label="输出字段取值SQL" prop="outputValueSql">
					<div style="display: flex;flex-direction: column;width: 100%;">
						<MonacoEditor
						  v-model="formData.outputValueSql"
						  :options="sqlEditorOptions"
						  language="sql"
						  style="height: 200px;"
						  @change="validateSQL"
						/>
						
						<div class="sql-tips">
						  <el-alert
							title="SQL编写提示"
							type="info"
							:closable="false"
						  >
							<template #default>
							  <p>1. SQL语句支持以SELECT、Delete、Update等</p>
							  <p>2. SQL必须包含参数标识字段: {{ formData.outputFieldIdentifier?.split('.').pop() }}</p>
							  <p>3. 查询结果的字段名必须与参数标识字段匹配</p>
							  <p>4. 如果输入字段为sql参数，编写sql示例:( field=${输入字段标识})</p>
							</template>
						  </el-alert>
						</div>
					</div>
				</el-form-item>
				
			</template>
			
			<!-- Redis缓存相关配置 -->
			<template v-if="formData.outputValueFromInput === 'redis'">
				<el-form-item label="Redis键" prop="outputValueRedisKey">
					<el-input v-model="formData.outputValueRedisKey" placeholder="请输入Redis键" />
				</el-form-item>
			</template>
			
			<el-form-item label="输出字段默认值" prop="outputFieldDefaultValue">
				<el-input 
					v-model="formData.outputFieldDefaultValue" 
					:placeholder="formData.outputValueFromInput === 'constant' ? '请输入常量值' : '请输入输出字段默认值'"
				/>
			</el-form-item>
			
			<!--逻辑条件-->
			<div class="section-title">
				<span class="title-form_primary">条件组配置</span>
				<el-button type="primary" link @click="addConditionGroup">
					添加条件组
				</el-button>
			</div>
			
			<div class="condition-content">
				<div class="section-title">
					<span class="title-form_primary">条件组列表</span>
					<el-button type="primary" link @click="addConditionGroup">
						<el-icon><Plus /></el-icon>添加条件组
					</el-button>
				</div>

				<div v-if="!formData.conditions?.length" class="empty-tip">
					<el-empty description="暂无条件组" />
				</div>

				<TransitionGroup 
					name="flip-list" 
					tag="div"
					v-else
				>
					<div v-for="(group, groupIndex) in formData.conditions" 
						:key="groupIndex" 
						class="condition-group"
					>
						<div class="group-header">
							<div class="group-info">
								<el-icon class="drag-handle"><Operation /></el-icon>
								<span class="group-title">条件组 {{groupIndex + 1}}</span>
								<el-tag size="small" type="info">
									{{ generateGroupExpression(group) }}
								</el-tag>
							</div>
							<div class="group-actions">
								<el-button type="primary" link @click="addCondition(groupIndex)">
									<el-icon><Plus /></el-icon>添加条件
								</el-button>
								<el-button type="danger" link @click="removeConditionGroup(groupIndex)">
									<el-icon><Delete /></el-icon>删除组
								</el-button>
							</div>
						</div>

						<div class="conditions-list">
							<TransitionGroup name="flip-list" tag="div">
								<div v-for="(condition, condIndex) in group.conditions" 
									:key="condIndex" 
									class="condition-item"
								>
									<div class="condition-content">
										<div class="condition-row">
											<el-select v-model="condition.relation" class="relation-select">
												<el-option value=">" label="大于" />
												<el-option value="<" label="小于" />
												<el-option value="==" label="等于" />
												<el-option value=">=" label="大于等于" />
												<el-option value="<=" label="小于等于" />
												<el-option value="!=" label="不等于" />
												<el-option value="in" label="包含于" />
												<el-option value="not in" label="不包含于" />
											</el-select>

											<div class="value-input">
												<template v-if="['in', 'not in'].includes(condition.relation)">
													<el-select
														v-model="condition.values"
														multiple
														filterable
														allow-create
														default-first-option
														placeholder="请输入值(回车分隔)"
														class="value-select"
													/>
												</template>
												<template v-else>
													<el-input 
														v-model="condition.value" 
														placeholder="请输入比较值"
														class="value-input"
													/>
												</template>
											</div>

											<el-button type="danger" link @click="removeCondition(groupIndex, condIndex)">
												<el-icon><Delete /></el-icon>
											</el-button>
										</div>

										<div v-if="condIndex < group.conditions.length - 1" class="logic-row">
											<el-radio-group v-model="condition.logic" class="logic-group">
												<el-radio-button value="&&">且</el-radio-button>
												<el-radio-button value="||">或</el-radio-button>
											</el-radio-group>
										</div>
									</div>
								</div>
							</TransitionGroup>
						</div>
					</div>
				</TransitionGroup>
			</div>
			
		</el-form>
		</el-scrollbar>
		<template #footer>
		  <div class="dialog-footer">
			<el-button type="primary" @click="submitForm" :loading="loading">确 定</el-button>
			<el-button @click="closeDialog" :loading="loading">取 消</el-button>
		  </div>
		</template>
	</el-drawer>
</template>

<script lang="ts" setup>
	import { ref, reactive } from "vue";
	import type { FormRules, FormInstance } from 'element-plus'
	import { ElMessage } from "element-plus";
	import { onMounted, watch } from "vue";
	import MonacoEditor from '@/components/MonacoEditor/index.vue'
	import DatasourceAPI from '@/api/biz/datasource';
	import { Plus, Delete, Operation } from '@element-plus/icons-vue'
	import { TransitionGroup } from 'vue'
	const emit = defineEmits(['success', 'closed']);
	const loading = ref(false);
	const dialog = ref({
		visible:false,
		title:'',
	});
	const rowIndex = ref<number>(1);
	const formRef=ref<FormInstance>();
	const formRules=reactive<FormRules>({
		inputFieldIdentifier: [
			{ required: true, message: "请输入输入字段标识", trigger: "blur" },
			{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: "标识符必须以字母开头，只能包含字母、数字和下划线", trigger: "blur" }
		],
		conditions: [
			{ 
				validator: (rule: any, value: any[], callback: Function) => {
					if (!value || value.length === 0) {
						callback(new Error('至少需要一个条件组'));
						return;
					}
					for (const group of value) {
						if (!group.conditions || group.conditions.length === 0) {
							callback(new Error('条件组不能为空'));
							return;
						}
						for (const condition of group.conditions) {
							if (!condition.relation) {
								callback(new Error('请选择关系运算符'));
								return;
							}
							if (['in', 'not in'].includes(condition.relation)) {
								if (!condition.values || condition.values.length === 0) {
									callback(new Error('请输入比较值'));
									return;
								}
							} else if (!condition.value) {
								callback(new Error('请输入比较值'));
								return;
							}
						}
					}
					callback();
				},
				trigger: 'change'
			}
		],
		sameFieldName: [
			{ required: true, message: "请选择是否字段名相同", trigger: "change" }
		],
		outputFieldName: [
			{ required: true, message: "请输入输出字段名", trigger: "blur" },
			{ min: 2, max: 50, message: "长度在 2 到 50 个字符", trigger: "blur" }
		],
		sameFieldIdentifier: [
			{ required: true, message: "请选择是否字段标识相同", trigger: "change" }
		],
		outputFieldIdentifier: [
			{ required: true, message: "请输入输出字段标识", trigger: "blur" },
			{ pattern: /^[a-zA-Z][a-zA-Z0-9_]*$/, message: "标识符必须以字母开头，只能包含字母、数字和下划线", trigger: "blur" }
		],
		outputFieldType: [
			{ required: true, message: "请选择输出字段类型", trigger: "change" }
		],
		outputFieldFormat: [
			{ required: true, message: "请选择输出字段格式", trigger: "change" }
		],
		outputFieldDecimalPoint: [
			{ required: true, message: "请输入输出字段保留小数位", trigger: "change" }
		],
		outputValueFromInput: [
			{ required: true, message: "请选择输出取值输入", trigger: "change" }
		],
		outputValueDatasourceId: [
			{ required: true, message: '请选择数据源', trigger: 'change' }
		],
		outputValueSql: [
			{ required: true, message: '请输入SQL语句', trigger: 'blur' }
		],
		outputValueRedisKey: [
			{ required: true, message: '请输入Redis键', trigger: 'blur' }
		],
		outputValueStorageType: [
			{ required: true, message: '请选择时序库存储类型', trigger: 'blur' }
		],
		outputFieldDefaultValue: [
			{ 
				required: true,
				message: "请输入常量值",
				trigger: "blur",
				validator: (_rule: any, value: string) => {
					if (formData.value.outputValueFromInput === 'constant' && !value) {
						return new Error('当输出值来源为常量值时，必须输入常量值');
					}
					return true;
				}
			}
		]
	});
	
	//数据源
	const formData=ref<any>({
		outputFieldDateFormatSrc: 'select',
		oltpDatasources: [],
		conditions: [],
		sameFieldName: '1',
		sameFieldIdentifier: '1'
	});
	
	
	const sqlEditorOptions = {
	  theme: 'vs-dark',
	  language: 'sql',
	  automaticLayout: true,
	  minimap: { enabled: false },
	  lineNumbers: 'on',
	  folding: true,
	  wordWrap: 'on',
	  fontSize: 14,
	  tabSize: 2,
	  formatOnPaste: true,
	  formatOnType: true,
	  suggestOnTriggerCharacters: true,
	  quickSuggestions: true,
	};
	
	const standardFields=ref<any>();
	
	// 获取OLTP数据源列表
	const datasourceOptions=ref<any>([]);
	
	const getOLTPDatasources= async ()=>{
		try {
			const data = await DatasourceAPI.options({});
			datasourceOptions.value = data.map((item:any) => ({
				id: item.id,
				name: item.name
			}));
		} catch (error:any) {
			console.error(error)
			ElMessage.error('获取OLTP下拉数据失败');
		}
	}
	
	const validateSQL = (_rule: any, value: string | undefined, callback: any): void => {
	  if ((!value || value.trim() === '') && formData.value.outputValueFromInput === 'OLTP') {
	    callback(new Error('请输入SQL语句'));
	    return;
	  }
	  
	  if (value && formData.value.outputValueFromInput === 'OLTP') {
	    // 检查是否包含参数标识字段
	    const identifier = formData.value.outputFieldIdentifier;
	    const columnName = identifier.split('.').pop(); // 获取最后一段作为字段名
	    
	    // SQL 必须以 SELECT 开头
	    // if (!value.trim().toLowerCase().startsWith('select')) {
	    //   callback(new Error('SQL语句必须以SELECT开头'));
	    //   return;
	    // }
	    
	    // 检查是否包含参数标识字段
	    const hasIdentifier = value.toLowerCase().includes(columnName.toLowerCase());
	    if (!hasIdentifier) {
	      callback(new Error(`SQL语句必须包含参数标识字段: ${columnName}`));
	      return;
	    }
	  }
	  callback();
	};
	
	const showStorageTypeField=ref<boolean>();
	async function openDialog(index: number,_row?: any,standards?:any, type?: string,storageType?:boolean) {
		if('add'==type){
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='新增字段';
			showStorageTypeField.value=storageType||false;
			standardFields.value=standards;
		}else{
			rowIndex.value=index;
			dialog.value.visible=true;
			dialog.value.title='编辑字段';
			showStorageTypeField.value=storageType||false;
			formData.value=JSON.parse(JSON.stringify(_row));
			standardFields.value=standards;
		}
		await getOLTPDatasources();
	}
	
	const submitForm=()=>{
		formRef.value.validate((isValid: boolean) => {
			if (isValid) {
				loading.value = true;
				emit('success', rowIndex.value, JSON.parse(JSON.stringify(formData.value)));
				loading.value = false;
				closeDialog();
			}
		});
	}
	
	const closeDialog=()=>{
		dialog.value.visible=false;
		dialog.value.title="";
		emit('closed')
		resetForm();
	}
	
	/**
	 * 重置表单
	 */
	function resetForm() {
		formRef.value.resetFields();
		formRef.value.clearValidate();
		formData.value={};
	}	
	
	defineExpose({
	  openDialog,closeDialog
	});
	
	onMounted(() => {
	});
	
	// 监听输入字段标识的变化
	watch(() => formData.value.inputFieldIdentifier, (newVal) => {
		if (newVal) {
			const selectedField = standardFields.value.find(
				(item: any) => item.outputFieldIdentifier === newVal
			);
			if (selectedField) {
				handleInputFieldSelect(selectedField);
			}
		}
	});
	
	// 处理输入字段选择
	const handleInputFieldSelect = (field: any) => {
		formData.value.inputFieldName = field.outputFieldName;
		formData.value.inputFieldIdentifier = field.outputFieldIdentifier;
		formData.value.inputFieldType = field.outputFieldType;
		
		if (formData.value.sameFieldName === '1') {
			formData.value.outputFieldName = field.outputFieldName;
		}
		if (formData.value.sameFieldIdentifier === '1') {
			formData.value.outputFieldIdentifier = field.outputFieldIdentifier;
		}
	};
	
	// 处理字段名相同性变化
	const handleSameFieldNameChange = (value: any) => {
		if (value === '1') {
			// 如果选择相同，则输出字段名与输入字段名保持一致
			formData.value.outputFieldName = formData.value.inputFieldName;
		}
	};
	
	// 处理字段标识相同性变化
	const handleSameFieldIdentifierChange = (value: any) => {
		if (value === '1') {
			// 如果选择相同，则输出字段标识与输入字段标识保持一致
			formData.value.outputFieldIdentifier = formData.value.inputFieldIdentifier;
		}
	};
	
	// 监听输入字段名变化
	watch(() => formData.value.inputFieldName, (newVal) => {
		if (formData.value.sameFieldName === '1') {
			formData.value.outputFieldName = newVal;
		}
	});
	
	// 监听输入字段标识变化
	watch(() => formData.value.inputFieldIdentifier, (newVal) => {
		if (formData.value.sameFieldIdentifier === '1') {
			formData.value.outputFieldIdentifier = newVal;
		}
	});
	
	// 监听输出值来源变化
	watch(() => formData.value.outputValueFromInput, (newVal) => {
		// 当切换到常量值时，清空默认值
		if (newVal === 'constant') {
		//	formData.value.outputFieldDefaultValue = '';
		}
		// 触发表单验证
		if (formRef.value) {
			formRef.value.validateField('outputFieldDefaultValue');
		}
	});
	
	// 添加条件组
	const addConditionGroup = () => {
		if (!formData.value.conditions) {
			formData.value.conditions = [];
		}
		formData.value.conditions.push({
			conditions: [{
				relation: '>',
				value: '',
				values: [],
				logic: '&&'
			}]
		});
	};
	
	// 添加条件
	const addCondition = (groupIndex: number) => {
		formData.value.conditions[groupIndex].conditions.push({
			relation: '>',
			value: '',
			values: [],
			logic: '&&'
		});
	};
	
	// 删除条件组
	const removeConditionGroup = (groupIndex: number) => {
		formData.value.conditions.splice(groupIndex, 1);
	};
	
	// 删除条件
	const removeCondition = (groupIndex: number, condIndex: number) => {
		const group = formData.value.conditions[groupIndex];
		if (group.conditions.length > 1) {
			group.conditions.splice(condIndex, 1);
		} else {
			ElMessage.warning('每个条件组至少需要保留一个条件');
		}
	};
	
	// 生成条件表达式
	const generateConditionExpression = () => {
		if (!formData.value.conditions || formData.value.conditions.length === 0) {
			return '';
		}
	
		const fieldIdentifier = formData.value.inputFieldIdentifier;
		
		return formData.value.conditions.map((group: any) => {
			const groupExpr = group.conditions.map((cond: any, index: number) => {
				let expr = '';
				if (['in', 'not in'].includes(cond.relation)) {
					const values = cond.values.map((v: any) => 
						typeof v === 'number' ? v : `'${v}'`
					).join(',');
					expr = `${fieldIdentifier} ${cond.relation} (${values})`;
				} else {
					const value = typeof cond.value === 'number' ? cond.value : `'${cond.value}'`;
					expr = `${fieldIdentifier} ${cond.relation} ${value}`;
				}
				return index < group.conditions.length - 1 ? `${expr} ${cond.logic}` : expr;
			}).join(' ');
			return `(${groupExpr})`;
		}).join(' || ');
	};

	// 生成单个条件组的表达式用于显示
	const generateGroupExpression = (group: any) => {
		if (!group.conditions?.length) return '';
		
		return group.conditions.map((cond: any, index: number) => {
			let expr = '';
			if (['in', 'not in'].includes(cond.relation)) {
				const values = (cond.values || []).join(',');
				expr = `${cond.relation} (${values})`;
			} else {
				expr = `${cond.relation} ${cond.value}`;
			}
			return index < group.conditions.length - 1 ? `${expr} ${cond.logic}` : expr;
		}).join(' ');
	};
</script>

<style scoped>
	.step-content{
		background-color: aliceblue;
		margin-top: 8px;
		padding: 8px;
		padding-top: 16px;
	}
	
	.section-title {
		display: flex;
		justify-content: space-between;
		align-items: center;
		margin: 20px 0;
		
		.title-form_primary {
			font-weight: 500;
			font-size: 14px;
			color: var(--el-text-color-primary);
			position: relative;
			padding-left: 10px;
			
			&:before {
				content: "";
				position: absolute;
				left: 0;
				top: 50%;
				transform: translateY(-50%);
				width: 3px;
				height: 14px;
				background-color: var(--el-color-primary);
				border-radius: 2px;
			}
		}
	}
	
	.condition-group {
		border: 1px solid var(--el-border-color-light);
		border-radius: 4px;
		padding: 15px;
		margin-bottom: 15px;
		background: var(--el-fill-color-light);
		
		.group-header {
			display: flex;
			justify-content: space-between;
			align-items: center;
			margin-bottom: 15px;
			padding-bottom: 10px;
			border-bottom: 1px solid var(--el-border-color-lighter);
			
			.group-title {
				font-weight: 500;
				color: var(--el-text-color-primary);
			}
			
			.group-actions {
				display: flex;
				gap: 8px;
			}
		}
	}
	
	.condition-item {
		margin-bottom: 15px;
		padding: 12px;
		background-color: var(--el-bg-color);
		border-radius: 4px;
		box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
		
		.el-row {
			margin-bottom: 10px;
		}
		
		.logic-row {
			margin-top: 8px;
			
			.logic-group {
				display: flex;
				justify-content: center;
			}
		}
	}

	.condition-content {
		margin: 20px 0;
		
		.empty-tip {
			text-align: center;
			padding: 40px 0;
			color: var(--el-text-color-secondary);
		}

		.condition-group {
			margin-bottom: 16px;
			border: 1px solid var(--el-border-color);
			border-radius: 8px;
			overflow: hidden;
			transition: all 0.3s;
			
			&:hover {
				box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
			}

			.group-header {
				padding: 12px 16px;
				background-color: var(--el-fill-color-light);
				border-bottom: 1px solid var(--el-border-color-lighter);
				display: flex;
				justify-content: space-between;
				align-items: center;

				.group-info {
					display: flex;
					align-items: center;
					gap: 8px;

					.group-title {
						font-weight: 500;
						color: var(--el-text-color-primary);
					}
				}

				.group-actions {
					display: flex;
					gap: 12px;
				}
			}

			.conditions-list {
				padding: 16px;
				background-color: var(--el-bg-color);
			}
		}

		.condition-item {
			margin-bottom: 12px;
			padding: 12px;
			border-radius: 4px;
			background-color: var(--el-fill-color-light);
			
			&:last-child {
				margin-bottom: 0;
			}

			.condition-row {
				display: flex;
				align-items: center;
				gap: 12px;

				.relation-select {
					width: 120px;
				}

				.value-input {
					flex: 1;
				}
			}

			.logic-row {
				margin-top: 12px;
				display: flex;
				justify-content: center;

				.logic-group {
					.el-radio-button__inner {
						padding: 8px 20px;
					}
				}
			}
		}
	}

	.flip-list-move {
		transition: transform 0.5s;
	}

	.flip-list-enter-active,
	.flip-list-leave-active {
		transition: all 0.5s;
	}

	.flip-list-enter-from,
	.flip-list-leave-to {
		opacity: 0;
		transform: translateX(30px);
	}
</style>